package com.atguigu.secutirydemo.config;

import com.alibaba.fastjson2.JSON;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.LogoutDsl;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;

import java.util.HashMap;

import static org.springframework.security.config.Customizer.withDefaults;

/**
 * ClassName: WebSecurityConfig
 * Package:
 * Description:
 *
 * @Author:xiaohei
 * @Create 2025/2/4 16:52
 * Version 1.0
 */
@Configuration
@EnableWebSecurity//Spring项目总需要添加此注解，SpringBoot项目中不需要     作用是开启SpringSecurity的自定义配置
@EnableMethodSecurity //开区基于方法的授权
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        //authorizeRequests()：开启授权保护
        //anyRequest()：对所有请求开启授权保护
        //authenticated()：已认证请求会自动被授权
        //开启授权保护
        http.authorizeRequests(
                authorize -> authorize
                        //具有USER_LIST权限的用户可以访问/user/list
//                        .requestMatchers("/user/list").hasAuthority("USER_LIST")
                        //具有USER_ADD权限的用户可以访问/user/add
//                        .requestMatchers("/user/add").hasAuthority("USER_ADD")
                        //对所有请求开启授权保护
//                        .requestMatchers("/user/**").hasRole("AMMID")
                        .anyRequest()
                        //已认证的请求会被自动授权
                        .authenticated()
        );

        http.formLogin(form ->
            form.loginPage("/login")
                    .permitAll()  //无需授权即可访问该页面
                    .usernameParameter("username") //配置自定义的表单用户参数
                    .passwordParameter("password") //配置自定义的表单密码参数
                    .failureUrl("/login?error")
                    .successHandler(new MyAuthenticationSuccessHandler())
                    .failureHandler(new MyAuthenticationFailureHandler()) //登录失败时的回调地址
        );//表单授权方式

        http.httpBasic(withDefaults());

        http.logout(logout ->
            logout.logoutSuccessHandler(new MyLogoutSuccessHandler())
        );//基本授权方式
        http.csrf(csrf -> csrf.disable());   //csrf攻击

        http.exceptionHandling(exception ->{
                exception.authenticationEntryPoint(new MyAuthenticationEntryPoint());
                exception.accessDeniedHandler((request, response, e)->{ //请求未授权的接口
                    //创建结果对象
                    HashMap result = new HashMap();
                    result.put("code", -1);
                    result.put("message", "没有权限");

                    //转换成json字符串
                    String json = JSON.toJSONString(result);

                    //返回响应
                    response.setContentType("application/json;charset=UTF-8");
                    response.getWriter().println(json);
                });
        }); //未登录请求来时时的回调地址

        http.cors(withDefaults());//跨域处理

        //会话管理
        http.sessionManagement(session -> {
            session.maximumSessions(1)//最大同时登录的会话数
                    .expiredSessionStrategy(new MySessionInformationExpiredStrategy()); //默认处理策略后登陆挤掉先登录的账号
        });     //同时多会话登录的处理策略
        return http.build();
    }
}